package com.mw.controller;

import com.mw.domain.Comment;
import com.mw.domain.News;
import com.mw.domain.User;
import com.mw.service.CommentService;
import com.mw.service.NewsService;
import com.mw.service.UserService;
import com.mw.util.PreviewDeal;
import com.mw.util.StringTool;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("")
public class NewsController {
    @Autowired
    NewsService newsService;
    @Autowired
    CommentService commentService;
    @Autowired
    UserService userService;

    /**
     * 初始获取20条新闻
     *
     * @param
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    public String showNews(ModelMap map) {
        Page<News> newsPage = newsService.getAllNewsTypeIsNotNull(0, 20);
//        List<News> newsList = newsPage.getContent();
        PreviewDeal previewDeal = new PreviewDeal();//预览图文工具
        List<News> newsList = previewDeal.Deal(newsPage.getContent());//设置预览图文
        map.addAttribute("News", newsList);
        int totalPages = newsPage.getTotalPages() - 1;
        map.addAttribute("totalPages", totalPages);
        return "index";
    }

    /**
     * 加载更多新闻
     *
     * @param pageNum 新闻页，即下一页
     * @return
     */
    @RequestMapping(value = "/loadmore")
    @ResponseBody
    public List<News> loadmore(@RequestParam(value = "pageNum", required = false) String pageNum) {
        int pageNumber = Integer.parseInt(pageNum);
        Page<News> newsPage = newsService.getAllNewsTypeIsNotNull(pageNumber, 20);
        PreviewDeal previewDeal = new PreviewDeal();//预览图文工具
        List<News> newsList = previewDeal.Deal(newsPage.getContent());//设置预览图文
        return newsList;
    }

    /**
     * 跳转到新闻
     *
     * @param id 新闻id
     * @param
     * @return 该id新闻页
     */
    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public String toNewsById(@PathVariable("id") Integer id, ModelMap map, HttpSession httpSession) {
        News news = newsService.getNewsById(Integer.valueOf(id));
        //用户喜好加分
        if (httpSession.getAttribute("user") != null) {
            User user = (User) httpSession.getAttribute("user");
            StringTool stringTool = new StringTool();
            user.setPreference(stringTool.typeAdd(user.getPreference(), news.getType(), 1));
            userService.saveUser(user);
        }
        //结束
        map.addAttribute("News", news);
        List<Comment> comments = commentService.getAllCommentByNid((id.toString()));
        Collections.reverse(comments);
        for (int i = 0; i < comments.size(); i++) {
            //将id换成用户名
            String uid = comments.get(i).getUid();
            String uName = userService.getUsernameById(Integer.valueOf(uid));
            comments.get(i).setUid("<a href =\"user/" + uid + "\">" + uName + "</a>");
            //判断是否是回复，做出处理
            String tid = comments.get(i).getTid();
            if (tid == null || tid == "") {
                comments.get(i).setTid("");
            } else {
                String tName = userService.getUsernameById(Integer.valueOf(tid));
                comments.get(i).setTid("回复<a href =\"user/" + tid + "\">@" + tName + "</a>:");
            }
        }
        map.addAttribute("Comments", comments);
        return "newspage";
    }

    /**
     * 根据标签找新闻
     *
     * @param map
     * @param label 标签
     * @return
     */
    @RequestMapping(value = "/label", method = RequestMethod.GET)
    public String toLabel(ModelMap map, String label) {
        Page<News> newsPage = newsService.getAllNewsHaveLabel(0, 20, label);
        PreviewDeal previewDeal = new PreviewDeal();//预览图文工具
        List<News> newsList = previewDeal.Deal(newsPage.getContent());//设置预览图文
        map.addAttribute("News", newsList);
        int totalPages = newsPage.getTotalPages() - 1;
        map.addAttribute("totalPages", totalPages);
        map.addAttribute("label", label);
        return "label";
    }

    /**
     * 加载更多新闻，带标签
     *
     * @param pageNum 新闻页，即下一页
     * @return
     */
    @RequestMapping(value = "/loadmorelabel")
    @ResponseBody
    public List<News> loadmore(@RequestParam(value = "pageNum", required = false) String pageNum,
                               @RequestParam(value = "label", required = false) String label) {
        int pageNumber = Integer.parseInt(pageNum);
        Page<News> newsPage = newsService.getAllNewsHaveLabel(pageNumber, 20, label);
        PreviewDeal previewDeal = new PreviewDeal();//预览图文工具
        List<News> newsList = previewDeal.Deal(newsPage.getContent());//设置预览图文
        return newsList;
    }

    @RequestMapping(value = "/foryou")
    @ResponseBody
    public Object foryou(HttpSession httpSession) {
        User user = (User) httpSession.getAttribute("user");
        StringTool stringTool = new StringTool();
        Map<String, Integer> map = stringTool.StringToMap(user.getPreference());
        if (map.size() < 6) {
            return "现在还不知道你的喜好，再多看看新闻吧。";
        }
        map.remove("明星");
        map.remove("时尚");
        map.remove("影视");
        map.remove("宠物");
        map.remove("生活");

        //将Map转化为List集合，List采用ArrayList
        List<Map.Entry<String, Integer>> list_Data = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
        //通过Collections.sort(List I,Comparator c)方法进行排序
        Collections.sort(list_Data, new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return (o2.getValue().compareTo(o1.getValue()));
            }
        });
        List<News> newsList = new ArrayList<>();
        //依喜好分数高的字段查找新闻，最多取5条。
        for (int c = 0; c < list_Data.size(); c++) {
            newsList.addAll(newsService.getAllNewsHaveLabel(0, 5, list_Data.get(c).getKey()).getContent());
            for (int i = 0; i < newsList.size() - 1; i++) {
                for (int j = newsList.size() - 1; j > i; j--) {
                    if (newsList.get(j).equals(newsList.get(i))) {
                        newsList.remove(j);
                    }
                }
            }
            if (newsList.size() > 5) {
                break;
            }
        }
        PreviewDeal previewDeal = new PreviewDeal();
        newsList = previewDeal.Deal(newsList);
        return newsList;
    }

    @RequestMapping(value = "/info")
    public String toInfo() {
        return "info";
    }

    @RequestMapping(value = "/newsdata")
    public String toNewsData(ModelMap modelMap) {
        List<News> newsList = newsService.getAllNewsByTypeIsNotNull();
        String s = "明星=0,时尚=0,影视=0,宠物=0,生活=0";
        StringTool stringTool = new StringTool();
        for (News news : newsList) {
            s = stringTool.typeAdd(s, news.getType(), 1);
        }

        //将Map转化为List集合，List采用ArrayList
        List<Map.Entry<String, Integer>> list_Data = new ArrayList<Map.Entry<String, Integer>>(stringTool.StringToMap(s).entrySet());
        //通过Collections.sort(List I,Comparator c)方法进行排序
        Collections.sort(list_Data, new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return (o2.getValue().compareTo(o1.getValue()));
            }
        });
        String txt = "<ul>";
        double total = 0;
        for (int i = 0; i < list_Data.size(); i++) {
            total += list_Data.get(i).getValue();
        }
        double width = 100 / (list_Data.get(0).getValue() / total);
        for (int i = 0; i < list_Data.size(); i++) {
            double w = (list_Data.get(i).getValue() / total) * width;
            txt += "<li style=\"width: " + String.format("%.2f", w) + "%\">"
                    + list_Data.get(i).getKey()
                    + ":" + list_Data.get(i).getValue() + "</li>";
        }
        txt += "</ul>";
        modelMap.addAttribute("newsdata", txt);
        return "newdata";
    }

    @RequestMapping("/download")
    public void downstudents(HttpServletResponse response) throws IOException {

        String[] headers = {"ID", "标题", "内容", "日期", "作者", "类型"};//导出的Excel头部

        List<News> dataset = newsService.getAllNewsByTypeIsNotNull();//查询出来的数据

        //下面的完全不动就行了（Excel数据中不包含图片）

        // 声明一个工作薄
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 生成一个表格
        HSSFSheet sheet = workbook.createSheet();
        // 设置表格默认列宽度为15个字节
        sheet.setDefaultColumnWidth((short) 18);
        HSSFRow row = sheet.createRow(0);
        for (short i = 0; i < headers.length; i++) {
            HSSFCell cell = row.createCell(i);
            HSSFRichTextString text = new HSSFRichTextString(headers[i]);
            cell.setCellValue(text);
        }
        //遍历集合数据，产生数据行
        Iterator<News> it = dataset.iterator();
        int index = 0;
        while (it.hasNext()) {
            index++;
            row = sheet.createRow(index);
            News t = (News) it.next();
            //利用反射，根据javabean属性的先后顺序，动态调用getXxx()方法得到属性值
            Field[] fields = t.getClass().getDeclaredFields();
            for (short i = 0; i < fields.length; i++) {
                HSSFCell cell = row.createCell(i);
                Field field = fields[i];
                String fieldName = field.getName();
                String getMethodName = "get"
                        + fieldName.substring(0, 1).toUpperCase()
                        + fieldName.substring(1);
                try {
                    Class tCls = t.getClass();
                    Method getMethod = tCls.getMethod(getMethodName,
                            new Class[]{});
                    Object value = getMethod.invoke(t, new Object[]{});
                    String textValue = null;
                    if(value != null){
                        if (value instanceof Date) {
                            Date date = (Date) value;
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            textValue = sdf.format(date);
                        } else {
                            //其它数据类型都当作字符串简单处理
                            textValue = value.toString();
                        }
                    }

                    HSSFRichTextString richString = new HSSFRichTextString(textValue);
                    HSSFFont font3 = workbook.createFont();
                    font3.setColor(HSSFColor.BLACK.index);//定义Excel数据颜色
                    richString.applyFont(font3);
                    cell.setCellValue(richString);

                } catch (SecurityException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        response.setContentType("application/octet-stream");
        response.setHeader("Content-disposition", "attachment;filename=createList.xls");//默认Excel名称
        response.flushBuffer();
        workbook.write(response.getOutputStream());
    }
}
